/*
 * This is a test program for netfilter
 *
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/ip.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("huzhifeng@twsz.com>");
MODULE_DESCRIPTION("netfilter sample");

#define BCMDBG
#ifdef BCMDBG
#define DEBUGP(fmt, args...) printk( fmt,  ## args);
#else
#define DEBUGP( fmt, args...)
#endif

static unsigned int test_func(unsigned int hook,
		  struct sk_buff *skb,
		  const struct net_device *in,
		  const struct net_device *out,
		  int (*okfn)(struct sk_buff *))
{
	struct iphdr *iph;
	
	if( NULL == skb ) {
		printk(KERN_EMERG "###hzf test netfilter:null skb###");
		return NF_ACCEPT;
	}

	iph = ip_hdr(skb);

	if( NULL == iph ) {
		printk(KERN_EMERG "###hzf test netfilter:null ip head###");
		return NF_ACCEPT;
	}
	
	if( iph->protocol == 0x01 ) {
		printk(KERN_EMERG "###hzf test netfilter:capture icmp data###");
		return NF_DROP;
	}

	return NF_ACCEPT;
}

static struct nf_hook_ops nf_test_ops __read_mostly = {
	.hook		= test_func,
	.owner		= THIS_MODULE,
	.pf			= PF_INET,
	.hooknum	= NF_INET_PRE_ROUTING,
	.priority		= NF_IP_PRI_FIRST,
};

static int __init init(void)
{
	int ret = 0;

	ret = nf_register_hook(&nf_test_ops);
	if (ret < 0) {
		DEBUGP("hzf test netfilter: can't register pre-routing hook.\n");
		return (ret);
	}

	printk(KERN_EMERG "hzf test netfilter: load success\n");

	return (0);
}

static void fini(void)
{
	nf_unregister_hook(&nf_test_ops);
	printk(KERN_EMERG "hzf test netfilter: unload success\n");
}

module_init(init);
module_exit(fini);
